from skimage.transform import rotate
from skimage.feature import local_binary_pattern
from skimage import data, io, data_dir, filters, feature
from skimage.color import label2rgb
import skimage
import torch
import numpy as np
import matplotlib.pyplot as plt
from PIL import Image
import cv2

# settings for LBP
radius = 1  # LBP算法中范围半径的取值
n_points = 8 * radius  # 领域像素点数

def euclidean_distance(qf, gf):
    m = qf.shape[0]
    n = gf.shape[0]
    dist_mat = torch.pow(qf, 2).sum(dim=1, keepdim=True).expand(m, n) + \
               torch.pow(gf, 2).sum(dim=1, keepdim=True).expand(n, m).t()
    # dist_mat.addmm_(1, -2, qf, gf.t())
    # dist_mat = torch.addmm(input=dist_mat, beta=1, mat1=qf, mat2=gf.t(), alpha=-2)
    dist_mat = dist_mat.addmm(qf, gf.t(), beta=1, alpha=-2)/qf.shape[1]
    return dist_mat.cpu().numpy()
# 显示到plt中，需要从BGR转化到RGB，若是cv2.imshow(win_name, image)，则不需要转化
def get_LBP(image, figure=0, show=False):
    image1 = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
    # gray = cv2.cvtColor(image1, cv2.COLOR_BGR2GRAY)
    # LBP处理
    # lbp = local_binary_pattern(gray, n_points, radius)
    # hsv = cv2.cvtColor(image1, cv2.COLOR_BGR2HSV)
    # v = cv2.split(hsv)[2]
    # lbp = local_binary_pattern(v, n_points, radius)
    if show:
        plt.figure(figure)
        plt.subplot(221)
        plt.imshow(image1)
        plt.subplot(222)
        plt.imshow(gray, plt.cm.gray)
        plt.subplot(223)
        plt.imshow(lbp, plt.cm.gray)
        plt.subplot(224)
        plt.imshow(lbp_v, plt.cm.gray)

    def split_image(image, size=(4, 3), figure=1):
        h_out, w_out = size
        h, w = image.shape[0:2]

        def get_index(h, h_out):
            idx_h = [0]
            stride_h = h // h_out
            for i in range(1, h_out):
                idx_h.append(i * stride_h)
            idx_h.append(h - 1)
            return idx_h

        idx_h = get_index(h, h_out)
        idx_w = get_index(w, w_out)
        block = []
        for i in range(h_out):
            for j in range(w_out):
                block.append(image[idx_h[i]:idx_h[i + 1], idx_w[j]:idx_w[j + 1]])
        return block

    blocks = split_image(lbp)
    hist = []
    for block in blocks:
        hist.append(cv2.calcHist([block.astype(np.uint8)], [0], None, [256], [0, 256]).reshape(-1))
    hist = np.array(hist).reshape(1,-1)
    return torch.from_numpy(hist).cuda()

if __name__ == '__main__':

    # 读取图像
    image1 = cv2.imread('00000002.png')
    image2 = cv2.imread('00000008.png')
    image3 = cv2.imread('00000899.png')
    image4 = cv2.imread('00001996.png')
    feat1 = get_LBP(image1)
    feat2 = get_LBP(image2, 1)
    feat3 = get_LBP(image3, 2)
    feat4 = get_LBP(image4, 3)
    query = feat1
    gallery = torch.cat((feat1,feat2,feat3,feat4),dim=0)
    dist = euclidean_distance(query,gallery)
    plt.plot(dist[-1])
    print(dist)
    plt.show()
